-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: superchain erc20 redesign #73
Conversation
* feat: add superchain erc20 bridge * fix: interfaces and versions
* refactor: use oz upgradeable erc20 as dependency * chore: update interfaces * fix: tests based on changes * refactor: remove op as dependency * feat: add check for supererc20 bridge on modifier * chore: update tests and interfaces * chore: update stack vars name on test * chore: remove empty gitmodules file * chore: update superchain weth errors
* test: add superchain erc20 bridge tests * test: add optimism superchain erc20 beacon tests * test: remove unnecessary test * test: tests fixes * test: tests fixes
* chore: update missing bridge on natspec * fix: natspecs --------- Co-authored-by: agusduha <[email protected]>
--------- Co-authored-by: agusduha <[email protected]>
* refactor: rename mint and burn functions on superchain erc20 * chore: rename optimism superchain erc20 to superchain erc20 * feat: create optimism superchain erc20 contract * chore: update natspec and errors * fix: superchain erc20 tests * refactor: make superchain erc20 abstract * refactor: move storage and erc20 metadata functions to implementation * chore: update interfaces * chore: update superchain erc20 events * fix: tests * fix: natspecs * fix: add semmver lock and snapshots * fix: remove unused imports * fix: natspecs --------- Co-authored-by: 0xDiscotech <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work guys <3
/// @param _to Address to mint tokens to. | ||
/// @param _amount Amount of tokens to mint. | ||
function __superchainMint(address _to, uint256 _amount) external virtual onlySuperchainERC20Bridge { | ||
if (_to == address(0)) revert ZeroAddress(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whats the reason to enforce this revert in the standard?
Also, if you go this path, why revert here and not in the SuperchainERC20Bridge
and save an external call?
/// @param _from Address to burn tokens from. | ||
/// @param _amount Amount of tokens to burn. | ||
function __superchainBurn(address _from, uint256 _amount) external virtual onlySuperchainERC20Bridge { | ||
if (_from == address(0)) revert ZeroAddress(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
|
||
/// @title SuperchainWETH | ||
/// @notice SuperchainWETH is a version of WETH that can be freely transfrered between chains | ||
/// within the superchain. SuperchainWETH can be converted into native ETH on chains that | ||
/// do not use a custom gas token. | ||
contract SuperchainWETH is WETH98, ISuperchainERC20Extensions, ISemver { | ||
contract SuperchainWETH is WETH98, ISuperchainWETH, ISemver { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not involved with SuperchainWETH
, but it seems like the design has a lot of differences with the SuperchainERC20
now. Can we push for an implementation update here?
/// @notice Tests the `relayERC20` mints the proper amount and emits the `RelayERC20` event. | ||
function testFuzz_relayERC20_succeeds(address _from, address _to, uint256 _amount, uint256 _source) public { | ||
/// @notice Tests the `burn` burns the amount and emits the `Burn` event. | ||
function testFuzz___superchainBurn_succeeds(address _from, uint256 _amount) public { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can add the new SuperchainBurn
event emision check here. Same for SuperchainMint
where it belongs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good guys!
Run all added/modified tests with the flag --fuzz-runs 100000
if possible so we reduce the possibilities of getting flaky errors.
A general question I have is, we are mentioning L2StandardBridge
in many places when the actual contract is called L2StandardBridgeInterop
. Should we change it to that, or given that it will most likely be merged into one eventually just leave it at L2StandardBridge
. What do you think?
/// @param _to Address to mint tokens to. | ||
/// @param _amount Amount of tokens to mint. | ||
function __superchainMint(address _to, uint256 _amount) external virtual onlySuperchainERC20Bridge { | ||
if (_to == address(0)) revert ZeroAddress(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure how i feel about having this check, it feels opinionated, users calling this can check it themselves if they want, tokens extending it can add it.
also minting happens async, so after the burn, so if the _to is address 0, the user will lose the tokens either way - if anything this check should be in the bridge
bytes memory message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount)); | ||
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), message); | ||
|
||
emit SendERC20(_token, msg.sender, _to, _amount, _chainId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick to past tense like we do for all events for cohesion in the codebase, same in relayERC20
. I know these are in present tense in the standard but we should change that
/// @notice Allows the SuperchainERC20Bridge to burn tokens. | ||
/// @param _from Address to burn tokens from. | ||
/// @param _amount Amount of tokens to burn. | ||
function __superchainBurn(address _from, uint256 _amount) external virtual onlySuperchainERC20Bridge { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the standard says these should be public, we can modify the standard for them to be external also if we prefer it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh good catch, I rather have them external to enforce the sender check :)
/// @param _from Address to burn tokens from. | ||
/// @param _amount Amount of tokens to burn. | ||
function __superchainBurn(address _from, uint256 _amount) external virtual onlySuperchainERC20Bridge { | ||
if (_from == address(0)) revert ZeroAddress(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same with this check, not fully convinced it's needed here
function sendERC20(address _token, address _to, uint256 _amount, uint256 _chainId) external { | ||
if (_to == address(0)) revert ZeroAddress(); | ||
|
||
ISuperchainERC20(_token).__superchainBurn(msg.sender, _amount); | ||
|
||
bytes memory message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount)); | ||
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), message); | ||
|
||
emit SendERC20(_token, msg.sender, _to, _amount, _chainId); | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic-wise this is approved for me. I am not approved yet because there are some changes I don't get on random files. Similarly, why was forge updated, isn't the version locked?
@@ -39,8 +39,6 @@ interface ISuperchainWETH { | |||
/// @param _dst Address to relay tokens to. | |||
/// @param _wad Amount of tokens to relay. | |||
function relayERC20(address _from, address _dst, uint256 _wad) external; | |||
|
|||
function __constructor__() external; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is smth that was added in develop
by the ones doing the OP contracts manager, it was added to many interfaces
This interface was not being used before so now we have to delete that function so that we dont have to implement it
@@ -65,7 +65,7 @@ contract FeeVaultWithdrawal is Script { | |||
} | |||
|
|||
/// @notice Logs the information relevant to the user. | |||
function log(uint256 _balance, address _recipient, address _vault) internal pure { | |||
function log(uint256 _balance, address _recipient, address _vault) internal view { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compiler error saying that the function uses console.log
and it should be view
ISuperchainERC20(_token).__superchainBurn(msg.sender, _amount); | ||
|
||
bytes memory message = abi.encodeCall(this.relayERC20, (_token, msg.sender, _to, _amount)); | ||
IL2ToL2CrossDomainMessenger(MESSENGER).sendMessage(_chainId, address(this), message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function now returns the hash of the message, we can debate whether to catch the return value and include this in the event in a following PR.
* fix: semver natspec check failure * fix: ignore mock contracts in semver natspec script * fix: error message
Closing this PR, continuing in #82 |
No description provided.